#include <exceptions.hpp>

namespace cubefs { namespace java {

bool ThrowCubefsException(JNIEnv *env, const char *source, const char *msg, BigInt data) {
    jclass clazz = env->FindClass("ru/teleology/cubefs/api/reflection/Factory");

    if (clazz == NULL) {
        return NULL;
    }

    jmethodID mid = env->GetStaticMethodID(clazz, "throwCubefsException", "(Ljava/lang/String;Ljava/lang/String;J)V");

    if (mid == NULL) {
        return false;
    }

    jstring jsource = env->NewStringUTF(source);
    if (jsource == NULL) {
        return false;
    }

    jstring jmsg = env->NewStringUTF(msg);
    if (jmsg == NULL) {
        return false;
    }

    env->CallStaticVoidMethod(clazz, mid, jsource, jmsg, data);

    env->DeleteLocalRef(clazz);

    return true;
}


bool ThrowNPEException(JNIEnv *env, const char *source, const char *msg) {
    jclass clazz = env->FindClass("ru/teleology/cubefs/api/reflection/Factory");

    if (clazz == NULL) {
        return NULL;
    }

    jmethodID mid = env->GetStaticMethodID(clazz, "throwNullPointerException", "(Ljava/lang/String;Ljava/lang/String;)V");

    if (mid == NULL) {
        return false;
    }

    jstring jsource = env->NewStringUTF(source);
    if (jsource == NULL) {
        return false;
    }

    jstring jmsg = env->NewStringUTF(msg);
    if (jmsg == NULL) {
        return false;
    }

    env->CallStaticVoidMethod(clazz, mid, jsource, jmsg);

    env->DeleteLocalRef(clazz);

    return true;
}




bool ThrowDispatchException(JNIEnv *env, const char *source, const char *msg, int code1, int code2) {
    jclass clazz = env->FindClass("ru/teleology/cubefs/api/reflection/Factory");

    if (clazz == NULL) {
        return NULL;
    }

    jmethodID mid = env->GetStaticMethodID(clazz, "throwDispatchException", "(Ljava/lang/String;Ljava/lang/String;II)V");

    if (mid == NULL) {
        return false;
    }

    jstring jsource = env->NewStringUTF(source);
    if (jsource == NULL) {
        return false;
    }

    jstring jmsg = env->NewStringUTF(msg);
    if (jmsg == NULL) {
        return false;
    }

    env->CallStaticVoidMethod(clazz, mid, jsource, jmsg, code1, code2);

    env->DeleteLocalRef(clazz);

    return true;
}


bool ThrowBoundsException(JNIEnv *env, const char *source, const char *msg, BigInt index, BigInt index1, BigInt index2) {
    jclass clazz = env->FindClass("ru/teleology/cubefs/api/reflection/Factory");

    if (clazz == NULL) {
        return NULL;
    }

    jmethodID mid = env->GetStaticMethodID(clazz, "throwBoundsException", "(Ljava/lang/String;Ljava/lang/String;JJJ)V");

    if (mid == NULL) {
        return false;
    }

    jstring jsource = env->NewStringUTF(source);
    if (jsource == NULL) {
        return false;
    }

    jstring jmsg = env->NewStringUTF(msg);
    if (jmsg == NULL) {
        return false;
    }

    env->CallStaticVoidMethod(clazz, mid, jsource, jmsg, index, index1, index2);

    env->DeleteLocalRef(clazz);

    return true;
}


bool ThrowTypeCastException(JNIEnv *env, const char *source, const char *msg, const Type* src, const Type* dst) {
    jclass clazz = env->FindClass("ru/teleology/cubefs/api/reflection/Factory");

    if (clazz == NULL) {
        return NULL;
    }

    jmethodID mid = env->GetStaticMethodID(clazz, "throwTypeCastException", "(Ljava/lang/String;Ljava/lang/String;JJ)V");

    if (mid == NULL) {
        return false;
    }

    jstring jsource = env->NewStringUTF(source);
    if (jsource == NULL) {
        return false;
    }

    jstring jmsg = env->NewStringUTF(msg);
    if (jmsg == NULL) {
        return false;
    }

    env->CallStaticVoidMethod(clazz, mid, jsource, jmsg, Ptr2Handle(src), Ptr2Handle(dst));

    env->DeleteLocalRef(clazz);

    return true;
}


}}